# Script to download weather files for SAM 
# Note: Requires NREL API key saved as environment variable "NREL_KEY"
library(pacman)
p_load(
  here, data.table, sf, tigris, janitor, dplyr, purrr, 
  stringr, httr, tictoc
)
options(tigris_use_cache = TRUE)

# Loading county shape files --------------------------------------------------
  states_sf = 
    states(year = 2015) |>
    clean_names()
  # County shapes
  county_sf =
    map_dfr(
      states_sf$statefp,
      counties,
      year = 2015
    ) |> 
    clean_names() |>
    st_centroid()
  # Turning into table with just info we need 
  county_dt = data.table(county_sf)[,.(
    geoid = as.integer(geoid), 
    geometry = st_as_text(geometry),
    lon = st_coordinates(county_sf$geometry)[,1],
    lat = st_coordinates(county_sf$geometry)[,2]
  )]
  fwrite(
    county_dt, 
    here('Data/electricity-generation/sam/county-dt.csv')
  )
  
# Function to request data for a specific geoid -------------------------------
get_nrel_weather = function(
  geoid_in, 
  county_dt,
  url = "http://developer.nrel.gov",
  path = "api/nsrdb/v2/solar/psm3-2-2-tmy-download.csv",
  attributes = "air_temperature,dew_point,dhi,dni,surface_albedo,wind_speed",
  name = "YOUR NAME",
  email = "your@email.edu",
  affiliation = "YOUR AFFILIATION",
  rate_limit = 1 #in seconds
){
  # Update status
  geometry = county_dt[geoid == geoid_in]$geometry
  start_time = Sys.time()
  # Make API request
  result_raw = GET(
      url = url, 
      path = path, 
      query = list(
        api_key = Sys.getenv('NREL_KEY'),
        wkt = geometry,
        attributes = attributes,
        names = "tmy-2022",
        utc="false",
        full_name = name,
        email = email,
        affiliation = affiliation,
        reason = "Academic",
        mailing_list = "false"
      )
    )
  # Convert into table 
  result_df = fread(content(result_raw, as = 'text'), fill = TRUE )
  # Save result 
  fwrite(
    result_df, 
    here(
      'Data/electricity-generation/sam/weather', 
      paste(
        result_df$`Location ID`[1],
        result_df$Latitude[1],
        result_df$Longitude[1],
        'tmy-2022.csv', 
        sep = "_"
      )
    )
  )
  if(is.null(result_df$`Location ID`[1])){
    nsrb_id = 'error'
  }else{
    nsrb_id = result_df$`Location ID`[1]
  }
  # Add geoid to list of completed files 
  fwrite(
    data.table(geoid = geoid_in, nsrb_id = nsrb_id),
    here("Data/electricity-generation/sam/nsrb-log.csv"), 
    append = TRUE
  )
  # Making sure we respect rate limit
  end_time = Sys.time()
  if(as.numeric(end_time - start_time) < rate_limit) {
    Sys.sleep(rate_limit - as.numeric(end_time - start_time))
  }
  return(end_time-start_time)
} 

# Function to run for all counties --------------------------------------------
run_all_geoids = function(county_dt, resume = FALSE){
  # Getting list of geoid's already run if we are resuming
  if(resume == TRUE){
    log_dt = fread(here("Data/electricity-generation/sam/nsrb-log.csv"))
    geoids_to_run = setdiff(county_dt$geoid, log_dt$geoid)
  }else{
    geoids_to_run = county_dt$geoid
  }
  # Getting and saving data from API
  if(length(geoids_to_run) > 0){
    map(
      geoids_to_run, 
      get_nrel_weather, 
      county_dt = county_dt, 
      .progress = TRUE
    )
  }
}

# Running it! -----------------------------------------------------------------
run_all_geoids(county_dt, resume = TRUE)
